Passed
Push — feature/add-2fa-support ( 23e818...85b1f3 )
by Chris
24:19 queued 11:16
created

ApplicationReviewRoot.handleStatusChange   A

Complexity

Conditions 2

Size

Total Lines 13
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 11
dl 0
loc 13
rs 9.85
c 0
b 0
f 0
1
/* eslint camelcase: "off", @typescript-eslint/camelcase: "off" */
2
import React from "react";
3
import ReactDOM from "react-dom";
4
5
// Internationalizations
6
import { injectIntl, defineMessages, WrappedComponentProps } from "react-intl";
7
8
import camelCase from "lodash/camelCase";
9
import Swal from "sweetalert2";
10
import {
11
  Application,
12
  ReviewStatus,
13
  ApplicationReview,
14
} from "../../models/types";
15
import * as route from "../../helpers/routes";
16
import ApplicationReviewWithNav from "./ApplicationReviewWithNav";
17
import { axios } from "../../api/base";
18
import IntlContainer from "../../IntlContainer";
19
20
interface ApplicationReviewRootProps {
21
  initApplication: Application;
22
  reviewStatuses: ReviewStatus[];
23
}
24
25
interface ApplicationReviewRootState {
26
  application: Application;
27
  isSaving: boolean;
28
}
29
30
interface ReviewSubmitForm {
31
  review_status_id?: number | null;
32
  notes?: string | null;
33
}
34
35
const localizations = defineMessages({
36
  oops: {
37
    id: "alert.oops",
38
    defaultMessage: "Oops...",
39
    description: "Modal notification text indicating something went wrong.",
40
  },
41
  somethingWrong: {
42
    id: "apl.reviewSaveFailed",
43
    defaultMessage:
44
      "Something went wrong while saving a review. Try again later.",
45
    description: "Error message for error while saving an application review.",
46
  },
47
});
48
49
class ApplicationReviewRoot extends React.Component<
50
  ApplicationReviewRootProps & WrappedComponentProps,
51
  ApplicationReviewRootState
52
> {
53
  public constructor(
54
    props: ApplicationReviewRootProps & WrappedComponentProps,
55
  ) {
56
    super(props);
57
    this.state = {
58
      application: props.initApplication,
59
      isSaving: false,
60
    };
61
    this.submitReview = this.submitReview.bind(this);
62
    this.handleStatusChange = this.handleStatusChange.bind(this);
63
    this.handleNotesChange = this.handleNotesChange.bind(this);
64
    this.updateReviewState = this.updateReviewState.bind(this);
65
  }
66
67
  protected updateReviewState(review: ApplicationReview): void {
68
    const { application } = this.state;
69
    const updatedApplication = Object.assign(application, {
70
      application_review: review,
71
    });
72
    this.setState({
73
      application: updatedApplication,
74
    });
75
  }
76
77
  protected submitReview(review: ReviewSubmitForm): Promise<void> {
78
    const { application } = this.state;
79
    const { intl } = this.props;
80
81
    this.setState({ isSaving: true });
82
83
    return axios
84
      .put(route.applicationReviewUpdate(intl.locale, application.id), review)
85
      .then(response => {
86
        const newReview = response.data as ApplicationReview;
87
        this.updateReviewState(newReview);
88
        this.setState({ isSaving: false });
89
      })
90
      .catch(() => {
91
        this.setState({ isSaving: false });
92
        Swal.fire({
93
          icon: "error",
94
          title: intl.formatMessage(localizations.oops),
95
          text: intl.formatMessage(localizations.somethingWrong),
96
        });
97
      });
98
  }
99
100
  protected handleStatusChange(
101
    applicationId: number,
102
    statusId: number | null,
103
  ): Promise<void> {
104
    const { application } = this.state;
105
    const oldReview = application.application_review
106
      ? application.application_review
107
      : {};
108
    const submitReview = Object.assign(oldReview, {
109
      review_status_id: statusId,
110
    });
111
    return this.submitReview(submitReview);
112
  }
113
114
  protected handleNotesChange(
115
    applicationId: number,
116
    notes: string | null,
117
  ): void {
118
    const { application } = this.state;
119
    const oldReview = application.application_review
120
      ? application.application_review
121
      : {};
122
    const submitReview = Object.assign(oldReview, {
123
      notes,
124
    });
125
    this.submitReview(submitReview);
126
  }
127
128
  public render(): React.ReactElement {
129
    const { reviewStatuses } = this.props;
130
    const { application, isSaving } = this.state;
131
    const reviewStatusOptions = reviewStatuses.map(status => ({
132
      value: status.id,
133
      label: camelCase(status.name),
134
    }));
135
    return (
136
      <div className="applicant-review container--layout-xl">
137
        <ApplicationReviewWithNav
138
          key={application.id}
139
          application={application}
140
          reviewStatusOptions={reviewStatusOptions}
141
          onStatusChange={this.handleStatusChange}
142
          onNotesChange={this.handleNotesChange}
143
          isSaving={isSaving}
144
        />
145
      </div>
146
    );
147
  }
148
}
149
150
if (document.getElementById("application-review-container")) {
151
  const container = document.getElementById(
152
    "application-review-container",
153
  ) as HTMLElement;
154
  if (
155
    container.hasAttribute("data-application") &&
156
    container.hasAttribute("data-review-statuses")
157
  ) {
158
    const applications = JSON.parse(container.getAttribute(
159
      "data-application",
160
    ) as string);
161
    const reviewStatuses = JSON.parse(container.getAttribute(
162
      "data-review-statuses",
163
    ) as string);
164
    const language = container.getAttribute("data-locale") as string;
165
    const IntlApplicationReviewRoot = injectIntl(ApplicationReviewRoot);
166
    ReactDOM.render(
167
      <IntlContainer locale={language}>
168
        <IntlApplicationReviewRoot
169
          initApplication={applications}
170
          reviewStatuses={reviewStatuses}
171
        />
172
      </IntlContainer>,
173
      container,
174
    );
175
  }
176
}
177
178
export default injectIntl(ApplicationReviewRoot);
179